<?php namespace Phpcmf\Controllers;

// 绑定账号
class Member extends \Phpcmf\Common {

    private $access_token;

    // 从微信菜单中进入授权
    public function index() {

        $code = \Phpcmf\Service::L('input')->get('code');
        $state = \Phpcmf\Service::L('input')->get('state');

        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->weixin['account']['appid'].'&secret='.$this->weixin['account']['appsecret'].'&code='.$code.'&state='.$state.'&grant_type=authorization_code';
        $rt = wx_get_https_json_data($url);
        if (!$rt['code']) {
            $this->_msg(0, $rt['msg']);
        }

        $user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $rt['data']['openid'])->getRow();
        if (!$user) {
            $rts = weixin_get_access_token();
            $rts['code'] && $this->access_token = $rts['msg'];
            $rts = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->access_token.'&openid='.$rt['data']['openid']);
            if (!$rts['code']) {
                $this->_msg(0, $rts['msg']);
            } elseif (!$rts['data']['nickname']) {
                //$this->_msg(0, '未获取到微信用户昵称');
            }
            $user = \Phpcmf\Service::M('User', APP_DIR)->insert_user($rts['data']);
        }

        $oid = $rt['data']['openid'];
        $rt = \Phpcmf\Service::M('member')->insert_oauth(0, 'login', [
            'oid' => $oid,
            'oauth' => 'wechat',
            'avatar' => $user['headimgurl'],
            'unionid' => (string)$user['unionid'],
            'nickname' => dr_emoji2html($user['nickname']?$user['nickname']:'微信用户'),
            'expire_at' => SYS_TIME,
            'access_token' => 0,
            'refresh_token' => 0,
        ], $state);
        if (!$rt['code']) {
            $this->_msg(0, $rt['msg']);
            exit;
        } else {
            if ($user['uid']) {
                // 验证是否存在
                $member = \Phpcmf\Service::M('member')->member_info($user['uid']);
                if (!$member) {
                    \Phpcmf\Service::M()->db->table('weixin_user')->where('uid', $user['uid'])->delete();
                }
            }
            dr_redirect($rt['msg']);
        }
        exit;
    }

    // 小程序读取手机号
    public function xcx_phone()
    {

        if (IS_POST) {

            if (!$_POST['js_code']) {
                $this->_json(0, 'js_code数据获取失败');
            }

            $rts = xcx_get_access_token();
            if (!$rts['code']) {
                $this->_json(0, $rts['msg']);
            }

            $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $rts['msg'];
            $rt = wx_post_https_json_data(($url), [
                'code' => $_POST['js_code']
            ]);
            $token = $rt['data'];
            if (!$token) {
                $this->_json(0, '手机号获取失败');
            } elseif (isset($token['errcode']) && $token['errcode']) {
                $this->_json(0, '手机号错误代码（' . $token['errcode'] . '）：' . $token['errmsg'] . ' appid=' . $this->weixin['xcx']['appid'] . '&secret=' . $this->weixin['xcx']['appsecret'] . '');
            }

            $this->_json(1, 'ok', $token['phone_info']['phoneNumber']);
        }
    }

    // 小程序登录
    public function xcx() {

        if (IS_POST) {

            $json = json_decode($_POST['json'], true);
            if (!$json) {
                $this->_json(0, 'POST数据解析失败');
            } elseif (!$_POST['js_code']) {
                $this->_json(0, 'js_code数据获取失败');
            }

            $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$this->weixin['xcx']['appid'].'&secret='.$this->weixin['xcx']['appsecret'].'&js_code='.$_POST['js_code'].'&grant_type=authorization_code';
            $token = json_decode(dr_catcher_data($url), true);
            if (!$token) {
                $this->_json(0, 'jscode2session获取失败');
            } elseif (isset($token['errcode']) && $token['errcode']) {
                $this->_json(0, 'jscode2session错误代码（'.$token['errcode'].'）：'.$token['errmsg'].' appid='.$this->weixin['xcx']['appid'].'&secret='.$this->weixin['xcx']['appsecret'].'');
            } elseif (!$token['openid']) {
                $this->_json(0, 'jscode2session:openid获取失败');
            }

            $rt = \Phpcmf\Service::M('member')->insert_oauth(0, 'login', [
                'oid' => $token['openid'],
                'oauth' => 'wxxcx',
                'avatar' => $json['avatarUrl'],
                'unionid' => (string)$token['unionid'],
                //'nickname' => dr_emoji2html($json['nickName']),
                'nickname' => dr_emoji2html($user['nickName']?$user['nickName']:'微信用户'),
                'expire_at' => SYS_TIME,
                'access_token' => $token['session_key'],
                'refresh_token' => '',
            ]);
            if (!$rt['code']) {
                $this->_json(0, $rt['msg']);
            }

            $oauth = \Phpcmf\Service::M()->table('member_oauth')->get($rt['code']);
            if (!$oauth) {
                $this->_json(0, '服务端储存用户失败');
            } elseif ($oauth['uid']) {
                $rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
                if (!$rt['code']) {
                    $this->_json(0, $rt['msg']);
                }
                $this->_json(1, 'login', $rt['data']);
            }

            if ($this->weixin['xcx']['login']) {
                // 直接登录
                $rt = \Phpcmf\Service::M('member')->register_oauth(0, $oauth);
                if ($rt['code']) {
                    // 登录成功
                    $this->_json(1, 'login', $rt['data']);
                } else {
                    $this->_json(0, $rt['msg']);
                }
            } else {
                // 提示注册
                $oauth['nickname'] = dr_html2emoji($oauth['nickname']?$oauth['nickname']:'微信用户');
                $this->_json(1, 'register', $oauth);
            }

        } else {
            $this->_json(0, '非POST提交');
        }

        exit;
    }

    // 小程序绑定账号
    public function xcx_bang() {

        if (IS_POST) {

            $oid = (int)\Phpcmf\Service::L('Input')->post('oid');
            $post = \Phpcmf\Service::L('Input')->post('data', true);
            if (!$post) {
                $this->_json(0, 'POST数据解析失败');
            } elseif (!$oid) {
                $this->_json(0, '小程序OpenId为空');
            }

            $oauth = \Phpcmf\Service::M()->table('member_oauth')->get($oid);
            if (!$oauth) {
                $this->_json(0, '服务端用户不存在');
            } elseif ($oauth['uid']) {
                $rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
                if (!$rt['code']) {
                    $this->_json(0, $rt['msg']);
                }
                $this->_json(1, 'ok', $rt['data']);
            }

            // 登录绑定
            if (empty($post['username']) || empty($post['password'])) {
                $this->_json(0, dr_lang('账号或密码必须填写'));
            } else {
                $rt = \Phpcmf\Service::M('member')->login($post['username'], $post['password']);
                if ($rt['code']) {
                    // 登录成功
                    \Phpcmf\Service::M()->db->table('member_oauth')->where('id', $oid)->update(['uid' => $rt['data']['member']['id']]);
                    $this->_json(1, 'ok', $rt['data']);
                } else {
                    $this->_json(0, $rt['msg']);
                }
            }

        } else {
            $this->_json(0, '非POST提交');
        }
    }

    // 小程序注册账号
    public function xcx_reg() {

        if (IS_POST) {

            $oid = (int)\Phpcmf\Service::L('Input')->post('oid');
            $post = \Phpcmf\Service::L('Input')->post('data', true);
            if (!$post) {
                $this->_json(0, 'POST数据解析失败');
            } elseif (!$oid) {
                $this->_json(0, '小程序OpenId为空');
            }

            $oauth = \Phpcmf\Service::M()->table('member_oauth')->get($oid);
            if (!$oauth) {
                $this->_json(0, '服务端用户不存在');
            } elseif ($oauth['uid']) {
                $rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
                if (!$rt['code']) {
                    $this->_json(0, $rt['msg']);
                }
                $this->_json(1, 'ok', $rt['data']);
            }

            // 注册

            if (empty($post['password'])) {
                $this->_json(0, dr_lang('密码必须填写'), ['field' => 'password']);
            } elseif ($post['password'] != $post['password2']) {
                $this->_json(0, dr_lang('确认密码不一致'), ['field' => 'password2']);
            } else {
                $rt = \Phpcmf\Service::M('member')->register_oauth_bang($oauth, 0, [
                    'username' => (string)$post['username'],
                    'phone' => (string)$post['phone'],
                    'email' => (string)$post['email'],
                    'password' => dr_safe_password($post['password']),
                    'name' => dr_safe_replace($post['name']),
                ]);
                if ($rt['code']) {
                    // 注册绑定成功
                    $this->_json(1, 'ok', $rt['data']);
                } else {
                    $this->_json(0, $rt['msg'], ['field' => $rt['data']['field']]);
                }
            }

        } else {
            $this->_json(0, '非POST提交');
        }
    }

    // 公众号浏览url弹出登录
    public function login() {

        $code = \Phpcmf\Service::L('input')->get('code');
        $state = \Phpcmf\Service::L('input')->get('state');

        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->weixin['account']['appid'].'&secret='.$this->weixin['account']['appsecret'].'&code='.$code.'&state='.$state.'&grant_type=authorization_code';
        $rt = wx_get_https_json_data($url);
        if (!$rt['code']) {
            $this->_msg(0, $rt['msg']);
        }

        // 刷新
        $rs = wx_get_https_json_data('https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$this->weixin['account']['appid'].'&grant_type=refresh_token&refresh_token='.$rt['data']['refresh_token']);
        if (!$rs['code']) {
            $this->_msg(0, $rs['msg']);
        }

        $rts = wx_get_https_json_data('https://api.weixin.qq.com/sns/userinfo?access_token='.$rs['data']['access_token'].'&openid='.$rt['data']['openid'].'&lang=zh_CN');
        if (!$rts['code']) {
            $this->_msg(0, $rts['msg']);
        } elseif (!$rts['data']['nickname']) {
            //$this->_msg(0, '未获取到微信用户昵称');
        }

        $user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $rt['data']['openid'])->getRow();
        if (!$user) {
            $user = \Phpcmf\Service::M('User', APP_DIR)->insert_user($rts['data']);
        } else {
            $user = \Phpcmf\Service::M('User', APP_DIR)->update_user($user, $rts['data']);
        }

        $oid = $rt['data']['openid'];
        $rt = \Phpcmf\Service::M('member')->insert_oauth(0, 'login', [
            'oid' => $oid,
            'oauth' => 'wechat',
            'avatar' => $user['headimgurl'],
            'unionid' => (string)$user['unionid'],
            'nickname' => dr_emoji2html($user['nickname']),
            'expire_at' => SYS_TIME,
            'access_token' => 0,
            'refresh_token' => 0,
        ], $state);
        if (!$rt['code']) {
            $this->_msg(0, $rt['msg']);
            exit;
        } else {
            if ($user['uid'] && $state) {
                // 存储cookie
                $member = \Phpcmf\Service::M('member')->member_info($user['uid']);
                if (!$member) {
                    \Phpcmf\Service::M()->db->table('weixin_user')->where('uid', $user['uid'])->delete();
                    dr_redirect($rt['msg']);
                    exit;
                }
                \Phpcmf\Service::M('member')->save_cookie($member, 1);
                $goto_url = urldecode($state);
                if (strpos($goto_url, 'is_admin_call')) {
                    // 存储后台回话
                    \Phpcmf\Service::M('auth')->save_login_auth('wechat', $user['uid']);
                    $goto_url.= '&uid='.$user['uid'];
                } elseif (strpos($state, DOMAIN_NAME) === false) {
                    // 域名不同的情况下
                    $rt = \Phpcmf\Service::M('member')->sso($member, 1);
                    $sso = '';
                    foreach ($rt as $url) {
                        $sso.= '<script src="'.$url.'"></script>';
                    }
                    $this->_msg(1, dr_lang('%s，欢迎回来', dr_html2emoji($user['nickname'])).$sso, $goto_url, 0);exit;
                }
                dr_redirect($goto_url);
            } else {
                dr_redirect($rt['msg']);
            }
        }
    }

    // 微信公众号绑定
    public function wxbang() {

        if (!$this->uid) {
            $ep = dr_safe_replace(\Phpcmf\Service::L('input')->get('ep'));
            $rt = \Phpcmf\Service::M()->table('member_oauth')->where('refresh_token', $ep)->where('uid>0')->where('oauth', 'wechat')->getRow();
            if ($rt) {
                // 为他登录
                // 存储cookie
                $this->uid = $rt['uid'];
                $this->member = \Phpcmf\Service::M('member')->get_member($this->uid);
                \Phpcmf\Service::M('member')->save_cookie($this->member);
                // 存储后台回话
                if (isset($_GET['is_admin_call'])) {
                    \Phpcmf\Service::M('auth')->save_login_auth('wechat', $this->uid);
                    $this->_json(1, 'ok', [
                        'url' => urldecode($_GET['is_admin_call']).'&uid='.$this->uid,
                        'sso' => \Phpcmf\Service::M('member')->sso($this->member, 1),
                    ]);
                } else {
                    $this->_json(1, 'ok', [
                        'sso' => \Phpcmf\Service::M('member')->sso($this->member, 1),
                    ]);
                }
            }
        } else {
            $rt = \Phpcmf\Service::M()->table('member_oauth')->where('uid', $this->uid)->where('oauth', 'wechat')->getRow();
        }

        if (!$rt) {
            $this->_json(0, '');
        } else {
            // 绑定成功更新头像
            list($cache_path) = dr_avatar_path();
            $path = $cache_path.dr_avatar_dir($this->uid);
            $file = $path.$this->uid.'.jpg';
            if (!is_file($file)) {
                // 没有头像下载头像
                $img = dr_catcher_data($rt['avatar']);
                if (strlen($img) > 20) {
                    if (!is_dir($path)) {
                        dr_mkdirs($path);
                    }
                    file_put_contents($file, $img);
                }
            }
            // 存储后台回话
            if (isset($_GET['is_admin_call'])) {
                \Phpcmf\Service::M('auth')->save_login_auth('wechat', $this->uid);
                $this->_json($rt['access_token'] ? 0 : 1, 'ok', [
                    'url' => urldecode($_GET['is_admin_call']).'&uid='.$this->uid,
                    'sso' => \Phpcmf\Service::M('member')->sso($this->member, 1),
                ]);
            } else {
                $this->_json($rt['access_token'] ? 0 : 1, 'ok', $rt);
            }
        }
    }

    // 公众号浏览url弹出登录 url
    public function login_url() {

        $url = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=weixin&c=member&m=login';
        if ($_GET['back'] && strpos($_GET['back'], 'c=member&m=login') === false) {
            $burl = $_GET['back'];
        } else {
            $burl = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=member';
        }
        dr_redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode($url).'&response_type=code&scope=snsapi_userinfo&state='.urlencode($burl).'#wechat_redirect');
    }

}
